<template>
  <div class="slider" ref="slider">
    <div class="slider-group" ref="sliderGroup">
      <slot>
      </slot>
    </div>
    <div class="dots">
      <!--active  是一个class 代表当前轮播的样式-->
      <span class="dot" :class="{active: currentPageIndex === index }" v-for="(item, index) in dots"></span>
    </div>
  </div>
</template>

<script type="text/ecmascript-6">
 /* 这个是用来操作dom的。添加class样式，，还不如直接用zepto*/
  import {addClass} from 'common/js/dom'
  //  这里导入了 bettscroll 滚动条封装
  import BScroll from 'better-scroll'

  export default {
    name: 'slider',
    props: {
      //  循环
      loop: {
        type: Boolean,
        default: true
      },
      //  自动轮播
      autoPlay: {
        type: Boolean,
        default: true
      },
      // 轮播定时
      interval: {
        type: Number,
        default: 4000
      }
    },
    data() {
      return {
        //  标识符
        dots: [],
        // 当前索引页
        currentPageIndex: -1
      }
    },
//     created:在模板渲染成html前调用，即通常初始化某些属性值，然后再渲染成视图。
// mounted:在模板渲染成html后调用，通常是初始化页面完成后，再对html的dom节点进行一些需要的操作。
//     //mounted和created区别
    //https://blog.csdn.net/xdnloveme/article/details/78035065
    mounted() {
      setTimeout(() => {
        //  初始化轮播的宽度
        this._setSliderWidth()
        // 初始化轮播点
        this._initDots()
        // 初始化轮播参数
        this._initSlider()
        // 自动播放
        if (this.autoPlay) {
          this._play()
        }
      }, 20)
      //  监听窗口尺寸变化是啊金
      window.addEventListener('resize', () => {
        if (!this.slider) {
          return
        }
        this._setSliderWidth(true)
        //  重新刷新滚动。。因为元素的宽高都发生了变化
        this.slider.refresh()
      })
    },
    destroyed() {
      //  定时销毁定时器。。免得一直在运行
      clearTimeout(this.timer)
    },
    methods: {
      _setSliderWidth(isResize) {
        this.children = this.$refs.sliderGroup.children
        let width = 0
        //  可视宽度
        let sliderWidth = this.$refs.slider.clientWidth
        // 遍历轮播项。添加slider-item类
        for ( let i = 0; i < this.children.length; i++) {
          let child = this.children[i]
          addClass(child, 'slider-item')
          // 设置轮播项的宽度
          child.style.width = sliderWidth + 'px'
          width += sliderWidth
        }
        //  所有可视区宽度相加 。。。
        //  循环直播，宽度除了所有轮播项的宽度以外，还需要再加两个
        //  这是默认的写法。长度为轮播项再额外加两个长度
        //  两倍宽度只是一开始的时候需要用到，其他时候不需要用到
        if (this.loop && !isResize) {
          width += 2 * sliderWidth
        }
        // 设置轮播的宽度
        this.$refs.sliderGroup.style.width = width + 'px'
      },
      _initSlider() {
        // 配置项介绍请看这个
        //https://github.com/ustbhuangyi/better-scroll/tree/next
        //scrollX  是滚动的方向
        //  这个组件库貌似还可以
        //https://didi.github.io/cube-ui/#/zh-CN/docs/create-api
        this.slider = new BScroll(this.$refs.slider, {
          // 横向滚动
          scrollX: true,
          // 纵向滚动
          scrollY: false,
          //生成滚动动画
          momentum: false,
          // 开启循环轮播，设置组件
          snap: true,
          //是否可以无缝循环轮播
          snapLoop: this.loop,
          //手指滑动时页面可切换的阈值
          snapThreshold: 0.2,
          // 轮播图切换的动画时间
          snapSpeed: 400,
          click:true
        })
        //  滚动结束时触发 scrollEnd
        // 设置当前指示器  slider是一个BScroll
        this.slider.on('scrollEnd', () => {
          //当 snap 为 true 时，获取滚动的当前页，返回的对象结构为 {x, y, pageX, pageY}，
          // 其中 x,y 代表滚动横向和纵向的位置；
          //pageX，pageY 表示横向和纵向的页面索引
          // 他这个滚动是按照项来滚动
          let pageIndex = this.slider.getCurrentPage().pageX;
          this.currentPageIndex = 0
          //  自动轮播实现
          if (this.autoPlay) {
            clearTimeout(this.timer)
            this._play()
          }
        })
      },
      _initDots() {
        // children是轮播项
        this.dots = new Array(this.children.length)
      },
      _play() {
        this.currentPageIndex=this.slider.getCurrentPage().pageX;
        let pageIndex = this.currentPageIndex + 1
        if(this.loop&&pageIndex>=(this.dots.length-1)){
          this.currentPageIndex=0
        }
        this.timer = setTimeout(() => {
          // goToPage 滚动到指定子元素。下一页。。
          //  goToPage适用于水平滚动的
          //scrollToElement(el, time, offsetX, offsetY, easing)
          // 适用于垂直滚动的
          // this.interval是轮播间隔时间
          this.slider.goToPage(pageIndex, 0, 400)
        }, this.interval)
      }
    }
  }
</script>

<style scoped lang="stylus" rel="stylesheet/stylus">
  @import "~common/stylus/variable"

  .slider
    min-height: 1px
    .slider-group
      position: relative
      overflow: hidden
      white-space: nowrap
      .slider-item
        float: left
        box-sizing: border-box
        overflow: hidden
        text-align: center
        a
          display: block
          width: 100%
          overflow: hidden
          text-decoration: none
        img
          display: block
          width: 100%
    .dots
      position: absolute
      right: 0
      left: 0
      bottom: 12px
      text-align: center
      font-size: 0
      .dot
        display: inline-block
        margin: 0 4px
        width: 8px
        height: 8px
        border-radius: 50%
        background: $color-text-l
        //当前轮播的指示器的样式
        &.active
          width: 20px
          border-radius: 5px
          background: $color-text-ll
</style>
